home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / FLTK-1.0.6 / src / Fl_cutpaste.cxx < prev    next >
Encoding:
C/C++ Source or Header  |  1999-03-02  |  4.7 KB  |  154 lines

  1. //
  2. // "$Id: Fl_cutpaste.cxx,v 1.6 1999/03/02 07:03:15 bill Exp $"
  3. //
  4. // Cut/paste code for the Fast Light Tool Kit (FLTK).
  5. //
  6. // Copyright 1998-1999 by Bill Spitzak and others.
  7. //
  8. // This library is free software; you can redistribute it and/or
  9. // modify it under the terms of the GNU Library General Public
  10. // License as published by the Free Software Foundation; either
  11. // version 2 of the License, or (at your option) any later version.
  12. //
  13. // This library is distributed in the hope that it will be useful,
  14. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16. // Library General Public License for more details.
  17. //
  18. // You should have received a copy of the GNU Library General Public
  19. // License along with this library; if not, write to the Free Software
  20. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  21. // USA.
  22. //
  23. // Please report all bugs and problems to "fltk-bugs@easysw.com".
  24. //
  25.  
  26. // Implementation of cut and paste.
  27.  
  28. // This is seperated from Fl.C mostly to test Fl::add_handler().
  29. // But this will save a small amount of code size in a program that
  30. // has no text editing fields or other things that call cut or paste.
  31.  
  32. #ifdef WIN32
  33. #include "Fl_cutpaste_win32.cxx"
  34. #else
  35.  
  36. #include <FL/Fl.H>
  37. #include <FL/x.H>
  38. #include <FL/Fl_Window.H>
  39. #include <string.h>
  40.  
  41. static char *selection_buffer;
  42. static int selection_length;
  43. static int selection_buffer_length;
  44. static char beenhere;
  45.  
  46. extern Fl_Widget *fl_selection_requestor; // widget doing request_paste()
  47.  
  48. static int selection_xevent_handler(int) {
  49.  
  50.   switch (fl_xevent->type) {
  51.  
  52.   case SelectionNotify: {
  53.     if (!fl_selection_requestor) return 0;
  54.     static char *pastebuffer;
  55.     if (pastebuffer) {XFree(pastebuffer); pastebuffer = 0;}
  56.     if (fl_xevent->xselection.property != 0) {
  57.       Atom a; int f; unsigned long n,b;
  58.       if (!XGetWindowProperty(fl_display,
  59.                   fl_xevent->xselection.requestor,
  60.                   fl_xevent->xselection.property,
  61.                   0,100000,1,0,&a,&f,&n,&b,
  62.                   (unsigned char**)&pastebuffer)) {
  63.     Fl::e_text = pastebuffer;
  64.     Fl::e_length = int(n);
  65.     fl_selection_requestor->handle(FL_PASTE);
  66.       }
  67.     }}
  68.     return 1;
  69.  
  70.   case SelectionClear:
  71.     Fl::selection_owner(0);
  72.     return 1;
  73.  
  74.   case SelectionRequest: {
  75.     XSelectionEvent e;
  76.     e.type = SelectionNotify;
  77.     e.display = fl_display;
  78.     e.requestor = fl_xevent->xselectionrequest.requestor;
  79.     e.selection = fl_xevent->xselectionrequest.selection;
  80.     e.target = fl_xevent->xselectionrequest.target;
  81.     e.time = fl_xevent->xselectionrequest.time;
  82.     if (fl_xevent->xselectionrequest.target != XA_STRING || !selection_length) {
  83.       e.property = 0;
  84.     } else {
  85.       e.property = fl_xevent->xselectionrequest.property;
  86.     }
  87.     if (e.property) {
  88.       XChangeProperty(fl_display, e.requestor, e.property,
  89.               XA_STRING, 8, 0, (unsigned char *)selection_buffer,
  90.               selection_length);
  91.     }
  92.     XSendEvent(fl_display, e.requestor, 0, 0, (XEvent *)&e);}
  93.     return 1;
  94.  
  95.   default:
  96.     return 0;
  97.   }
  98. }
  99.  
  100. ////////////////////////////////////////////////////////////////
  101.  
  102. // Call this when a "paste" operation happens:
  103. void Fl::paste(Fl_Widget &receiver) {
  104.   if (selection_owner()) {
  105.     // We already have it, do it quickly without window server.
  106.     // Notice that the text is clobbered if set_selection is
  107.     // called in response to FL_PASTE!
  108.     Fl::e_text = selection_buffer;
  109.     Fl::e_length = selection_length;
  110.     receiver.handle(FL_PASTE);
  111.     return;
  112.   }
  113.   // otherwise get the window server to return it:
  114.   fl_selection_requestor = &receiver;
  115.   XConvertSelection(fl_display, XA_PRIMARY, XA_STRING, XA_PRIMARY,
  116.             fl_xid(Fl::first_window()), fl_event_time);
  117.   if (!beenhere) {
  118.     Fl::add_handler(selection_xevent_handler);
  119.     beenhere = 1;
  120.   }
  121. }
  122.  
  123. ////////////////////////////////////////////////////////////////
  124.  
  125. // call this when you create a selection:
  126. void Fl::selection(Fl_Widget &owner, const char *stuff, int len) {
  127.   if (!stuff || len<0) return;
  128.   if (len+1 > selection_buffer_length) {
  129.     delete[] selection_buffer;
  130.     selection_buffer = new char[len+100];
  131.     selection_buffer_length = len+100;
  132.   }
  133.   memcpy(selection_buffer, stuff, len);
  134.   selection_buffer[len] = 0; // needed for direct paste
  135.   selection_length = len;
  136.   selection_owner(&owner);
  137.   static Window selxid; // window X thinks selection belongs to
  138.   if (!selxid) selxid =
  139.          XCreateSimpleWindow(fl_display, 
  140.                      RootWindow(fl_display, fl_screen),
  141.                      0,0,1,1,0,0,0);
  142.   XSetSelectionOwner(fl_display, XA_PRIMARY, selxid, fl_event_time);
  143.   if (!beenhere) {
  144.     Fl::add_handler(selection_xevent_handler);
  145.     beenhere = 1;
  146.   }
  147. }
  148.  
  149. #endif
  150.  
  151. //
  152. // End of "$Id: Fl_cutpaste.cxx,v 1.6 1999/03/02 07:03:15 bill Exp $".
  153. //
  154.